<?php
/**
 * Zend Framework
 * LICENSE
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 * @category Zend
 * @package Zend_Form
 * @subpackage Decorator
 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 * @license http://framework.zend.com/license/new-bsd New BSD License
 */
/**
 * Zend_Form_Decorator_Abstract
 */
require_once 'Zend/Form/Decorator/Abstract.php';

/**
 * Zend_Form_Decorator_FormErrors
 * Displays all form errors in one view.
 * Any options passed will be used as HTML attributes of the ul tag for the errors.
 * @category Zend
 * @package Zend_Form
 * @subpackage Decorator
 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 * @license http://framework.zend.com/license/new-bsd New BSD License
 * @version $Id: FormErrors.php 25257 2013-02-13 16:47:18Z frosch $
 */
class Zend_Form_Decorator_FormErrors extends Zend_Form_Decorator_Abstract {

    /**
     * Default values for markup options
     * @var array
     */
    protected $_defaults = array('ignoreSubForms' => false, 'showCustomFormErrors' => true, 'onlyCustomFormErrors' => false, 'markupElementLabelEnd' => '</b>', 'markupElementLabelStart' => '<b>', 'markupListEnd' => '</ul>', 'markupListItemEnd' => '</li>', 'markupListItemStart' => '<li>', 'markupListStart' => '<ul class="form-errors">');

    /**
     * #@+
     * Markup options
     * @var string
     */
    protected $_ignoreSubForms;

    protected $_showCustomFormErrors;

    protected $_onlyCustomFormErrors;

    protected $_markupElementLabelEnd;

    protected $_markupElementLabelStart;

    protected $_markupListEnd;

    protected $_markupListItemEnd;

    protected $_markupListItemStart;

    protected $_markupListStart;

    /**
     * #@-
     */
    /**
     * Whether or not to escape error label and error message
     * @var bool
     */
    protected $_escape;

    /**
     * Render errors
     * @param string $content
     * @return string
     */
    public function render ($content) {
        $form = $this -> getElement ();
        if ( ! $form instanceof Zend_Form) {
            return $content;
        }
        $view = $form -> getView ();
        if (null === $view) {
            return $content;
        }
        $this -> initOptions ();
        $markup = $this -> _recurseForm ($form, $view);
        if (empty ($markup)) {
            return $content;
        }
        $markup = $this -> getMarkupListStart () . $markup . $this -> getMarkupListEnd ();
        switch ($this -> getPlacement ()) {
            case self::APPEND :
                return $content . $this -> getSeparator () . $markup;
            case self::PREPEND :
                return $markup . $this -> getSeparator () . $content;
        }
    }

    /**
     * Initialize options
     * @return void
     */
    public function initOptions () {
        $this -> getMarkupElementLabelEnd ();
        $this -> getMarkupElementLabelStart ();
        $this -> getMarkupListEnd ();
        $this -> getMarkupListItemEnd ();
        $this -> getMarkupListItemStart ();
        $this -> getMarkupListStart ();
        $this -> getPlacement ();
        $this -> getSeparator ();
        $this -> ignoreSubForms ();
        $this -> getShowCustomFormErrors ();
        $this -> getOnlyCustomFormErrors ();
    }

    /**
     * Retrieve markupElementLabelStart
     * @return string
     */
    public function getMarkupElementLabelStart () {
        if (null === $this -> _markupElementLabelStart) {
            if (null === ($markupElementLabelStart = $this -> getOption ('markupElementLabelStart'))) {
                $this -> setMarkupElementLabelStart ($this -> _defaults['markupElementLabelStart']);
            } else {
                $this -> setMarkupElementLabelStart ($markupElementLabelStart);
                $this -> removeOption ('markupElementLabelStart');
            }
        }
        return $this -> _markupElementLabelStart;
    }

    /**
     * Set markupElementLabelStart
     * @param string $markupElementLabelStart
     * @return Zend_Form_Decorator_FormErrors
     */
    public function setMarkupElementLabelStart ($markupElementLabelStart) {
        $this -> _markupElementLabelStart = $markupElementLabelStart;
        return $this;
    }

    /**
     * Retrieve markupElementLabelEnd
     * @return string
     */
    public function getMarkupElementLabelEnd () {
        if (null === $this -> _markupElementLabelEnd) {
            if (null === ($markupElementLabelEnd = $this -> getOption ('markupElementLabelEnd'))) {
                $this -> setMarkupElementLabelEnd ($this -> _defaults['markupElementLabelEnd']);
            } else {
                $this -> setMarkupElementLabelEnd ($markupElementLabelEnd);
                $this -> removeOption ('markupElementLabelEnd');
            }
        }
        return $this -> _markupElementLabelEnd;
    }

    /**
     * Set markupElementLabelEnd
     * @param string $markupElementLabelEnd
     * @return Zend_Form_Decorator_FormErrors
     */
    public function setMarkupElementLabelEnd ($markupElementLabelEnd) {
        $this -> _markupElementLabelEnd = $markupElementLabelEnd;
        return $this;
    }

    /**
     * Retrieve markupListStart
     * @return string
     */
    public function getMarkupListStart () {
        if (null === $this -> _markupListStart) {
            if (null === ($markupListStart = $this -> getOption ('markupListStart'))) {
                $this -> setMarkupListStart ($this -> _defaults['markupListStart']);
            } else {
                $this -> setMarkupListStart ($markupListStart);
                $this -> removeOption ('markupListStart');
            }
        }
        return $this -> _markupListStart;
    }

    /**
     * Set markupListStart
     * @param string $markupListStart
     * @return Zend_Form_Decorator_FormErrors
     */
    public function setMarkupListStart ($markupListStart) {
        $this -> _markupListStart = $markupListStart;
        return $this;
    }

    /**
     * Retrieve markupListEnd
     * @return string
     */
    public function getMarkupListEnd () {
        if (null === $this -> _markupListEnd) {
            if (null === ($markupListEnd = $this -> getOption ('markupListEnd'))) {
                $this -> setMarkupListEnd ($this -> _defaults['markupListEnd']);
            } else {
                $this -> setMarkupListEnd ($markupListEnd);
                $this -> removeOption ('markupListEnd');
            }
        }
        return $this -> _markupListEnd;
    }

    /**
     * Set markupListEnd
     * @param string $markupListEnd
     * @return Zend_Form_Decorator_FormErrors
     */
    public function setMarkupListEnd ($markupListEnd) {
        $this -> _markupListEnd = $markupListEnd;
        return $this;
    }

    /**
     * Retrieve markupListItemStart
     * @return string
     */
    public function getMarkupListItemStart () {
        if (null === $this -> _markupListItemStart) {
            if (null === ($markupListItemStart = $this -> getOption ('markupListItemStart'))) {
                $this -> setMarkupListItemStart ($this -> _defaults['markupListItemStart']);
            } else {
                $this -> setMarkupListItemStart ($markupListItemStart);
                $this -> removeOption ('markupListItemStart');
            }
        }
        return $this -> _markupListItemStart;
    }

    /**
     * Set markupListItemStart
     * @param string $markupListItemStart
     * @return Zend_Form_Decorator_FormErrors
     */
    public function setMarkupListItemStart ($markupListItemStart) {
        $this -> _markupListItemStart = $markupListItemStart;
        return $this;
    }

    /**
     * Retrieve markupListItemEnd
     * @return string
     */
    public function getMarkupListItemEnd () {
        if (null === $this -> _markupListItemEnd) {
            if (null === ($markupListItemEnd = $this -> getOption ('markupListItemEnd'))) {
                $this -> setMarkupListItemEnd ($this -> _defaults['markupListItemEnd']);
            } else {
                $this -> setMarkupListItemEnd ($markupListItemEnd);
                $this -> removeOption ('markupListItemEnd');
            }
        }
        return $this -> _markupListItemEnd;
    }

    /**
     * Set markupListItemEnd
     * @param string $markupListItemEnd
     * @return Zend_Form_Decorator_FormErrors
     */
    public function setMarkupListItemEnd ($markupListItemEnd) {
        $this -> _markupListItemEnd = $markupListItemEnd;
        return $this;
    }

    /**
     * Retrieve ignoreSubForms
     * @return bool
     */
    public function ignoreSubForms () {
        if (null === $this -> _ignoreSubForms) {
            if (null === ($ignoreSubForms = $this -> getOption ('ignoreSubForms'))) {
                $this -> setIgnoreSubForms ($this -> _defaults['ignoreSubForms']);
            } else {
                $this -> setIgnoreSubForms ($ignoreSubForms);
                $this -> removeOption ('ignoreSubForms');
            }
        }
        return $this -> _ignoreSubForms;
    }

    /**
     * Set ignoreSubForms
     * @param bool $ignoreSubForms
     * @return Zend_Form_Decorator_FormErrors
     */
    public function setIgnoreSubForms ($ignoreSubForms) {
        $this -> _ignoreSubForms = (bool) $ignoreSubForms;
        return $this;
    }

    /**
     * Get showCustomFormErrors
     * @return bool
     */
    public function getShowCustomFormErrors () {
        if (null === $this -> _showCustomFormErrors) {
            if (null === ($show = $this -> getOption ('showCustomFormErrors'))) {
                $this -> setShowCustomFormErrors ($this -> _defaults['showCustomFormErrors']);
            } else {
                $this -> setShowCustomFormErrors ($show);
                $this -> removeOption ('showCustomFormErrors');
            }
        }
        return $this -> _showCustomFormErrors;
    }

    /**
     * Set showCustomFormErrors
     * @param bool $showCustomFormErrors
     * @return Zend_Form_Decorator_FormErrors
     */
    public function setShowCustomFormErrors ($showCustomFormErrors) {
        $this -> _showCustomFormErrors = (bool) $showCustomFormErrors;
        return $this;
    }

    /**
     * Get onlyCustomFormErrors
     * @return bool
     */
    public function getOnlyCustomFormErrors () {
        if (null === $this -> _onlyCustomFormErrors) {
            if (null === ($show = $this -> getOption ('onlyCustomFormErrors'))) {
                $this -> setOnlyCustomFormErrors ($this -> _defaults['onlyCustomFormErrors']);
            } else {
                $this -> setOnlyCustomFormErrors ($show);
                $this -> removeOption ('onlyCustomFormErrors');
            }
        }
        return $this -> _onlyCustomFormErrors;
    }

    /**
     * Set onlyCustomFormErrors, whether to display elements messages
     * in addition to custom form messages.
     * @param bool $onlyCustomFormErrors
     * @return Zend_Form_Decorator_FormErrors
     */
    public function setOnlyCustomFormErrors ($onlyCustomFormErrors) {
        $this -> _onlyCustomFormErrors = (bool) $onlyCustomFormErrors;
        return $this;
    }

    /**
     * Set whether or not to escape error label and error message
     * Sets also the 'escape' option for the view helper
     * @param bool $flag
     * @return Zend_Form_Decorator_FormErrors
     */
    public function setEscape ($flag) {
        $this -> _escape = (bool) $flag;
        // Set also option for view helper
        $this -> setOption ('escape', $this -> _escape);
        return $this;
    }

    /**
     * Get escape flag
     * @return bool
     */
    public function getEscape () {
        if (null === $this -> _escape) {
            if (null !== ($escape = $this -> getOption ('escape'))) {
                $this -> setEscape ($escape);
            } else {
                $this -> setEscape (true);
            }
        }
        return $this -> _escape;
    }

    /**
     * Render element label
     * @param Zend_Form_Element $element
     * @param Zend_View_Interface $view
     * @return string
     */
    public function renderLabel (Zend_Form_Element $element, Zend_View_Interface $view) {
        $label = $element -> getLabel ();
        if (empty ($label)) {
            $label = $element -> getName ();
            // Translate element name
            if (null !== ($translator = $element -> getTranslator ())) {
                $label = $translator -> translate ($label);
            }
        }
        if ($this -> getEscape ()) {
            $label = $view -> escape ($label);
        }
        return $this -> getMarkupElementLabelStart () . $label . $this -> getMarkupElementLabelEnd ();
    }

    /**
     * Recurse through a form object, rendering errors
     * @param Zend_Form $form
     * @param Zend_View_Interface $view
     * @return string
     */
    protected function _recurseForm (Zend_Form $form, Zend_View_Interface $view) {
        $content = '';
        $custom = $form -> getCustomMessages ();
        if ($this -> getShowCustomFormErrors () && count ($custom)) {
            $content .= $this -> getMarkupListItemStart () . $view -> formErrors ($custom, $this -> getOptions ()) . $this -> getMarkupListItemEnd ();
        }
        foreach ($form -> getElementsAndSubFormsOrdered () as $subitem) {
            if ($subitem instanceof Zend_Form_Element &&  ! $this -> getOnlyCustomFormErrors ()) {
                $messages = $subitem -> getMessages ();
                if (count ($messages)) {
                    $subitem -> setView ($view);
                    $content .= $this -> getMarkupListItemStart () . $this -> renderLabel ($subitem, $view) . $view -> formErrors ($messages, $this -> getOptions ()) . $this -> getMarkupListItemEnd ();
                }
            } else 
                if ($subitem instanceof Zend_Form &&  ! $this -> ignoreSubForms ()) {
                    $markup = $this -> _recurseForm ($subitem, $view);
                    if ( ! empty ($markup)) {
                        $content .= $this -> getMarkupListStart () . $markup . $this -> getMarkupListEnd ();
                    }
                }
        }
        return $content;
    }

}
